/* 
Readonly<T> 新T中所有属性只读
Partial<T> 新T中所有属性可选
Required<T> 新T中所有属性必选

Exclude<T,U> 新T中没有U的部分
Extract<T,U> 新T中只有U的部分

要会手写这几个泛型工具
*/



/* T extends U ? X : Y */
interface Animal {
    name: string,
    life: number
}

/* 人类 */
interface Human extends Animal {
    think(): void
}

/* 机器人 */
interface Robot {
    name: string,
    think(): void
}

/* Extract 与U同类时T可用 */
/* type Extract<T, U> = T extends U ? T : never; */
type A = Extract<Human, Animal>
const value: A = {
    think: function (): void {
        throw new Error("Function not implemented.")
    },
    name: "",
    life: 0
}

type B = Extract<Robot, Animal>
// const value2:B = {}


/* Exclude 与U不同类时T可用 */
/* type Exclude<T, U> = T extends U ? never : T */
type C = Exclude<Robot, Animal>



// type MyUnion = string | number | boolean;
// // 从联合类型中剔除 string | number
// type MyFilteredUnion = Exclude<MyUnion, boolean>;


type MyUnion = string | number | boolean;
type MyExtractedUnion = Extract<MyUnion, string | object>;





/* ReadOnly 将T中所有的属性都变只读 */
type RoAnimal = Readonly<Animal>
const myPig: RoAnimal = {
    name: "猪猪",
    life: 10
}
// myPig.life += 10


/* Partial 将T中所有属性都变可选 */
type PartAnimal = Partial<Animal>
const myPig2: PartAnimal = {
    name: "二师兄"
}



/* 植物 */
interface Plant {
    name?: string,
    life?: number
}
const p1: Plant = {}

/* Required 将T中所有属性都变必选 */
type NewPlant = Required<Plant>
const p2: NewPlant = {}//类型“{}”缺少类型“Required<Plant>”中的以下属性: name, life





